#ifndef GRAPH_H
#define GRAPH_H

#include <vector>
#include <iostream>
#include "Adjiacency_Matrix.h"
#include "Adjiacency_List.h"

enum STORE_TYPE
{
    MATRIX,
    LIST
};

template<typename V>
class Graph
{
private:
    Adjiacency_List<V> * graph_L = nullptr;
    Adjiacency_Matrix<V> * graph_M = nullptr;
    STORE_TYPE type;
    
public:
    Graph(const std::vector<V> & _vertices, bool _isDirected = false, bool _isWeighted = false, STORE_TYPE _type = LIST, double _invalidWeight = 0): type{_type}
	{
	    switch (type)
	    {
		case LIST:		    
		    graph_L = new Adjiacency_List(_vertices, _isDirected, _isWeighted);
		    break;
	        case MATRIX:
		    graph_M = new Adjiacency_Matrix(_vertices, _isDirected, _isWeighted, _invalidWeight);
		    break;		
		default:
		    std::cerr << "Wrong Storage Type!" << std::endl;
		    exit(-1);
	    }
	}
    
    // 析构函数
    ~Graph()
	{
	    if(graph_L)
	    {
		delete graph_L;
		graph_L = nullptr;
	    }

	    if(graph_M)
	    {
		delete graph_M;
		graph_M = nullptr;
	    }
	}

    // 向图中添加一条边
    void add_edge(const V & v1, const V & v2) /// 无权图
	{
	    if(type == LIST)
		graph_L->add_edge(v1,v2);
	    else
		graph_M->add_edge(v1,v2);
	}
    void add_edge(const V & v1, const V & v2, double weight) /// 有权图
	{
	    if(type == LIST)
		graph_L->add_edge(v1,v2,weight);
	    else
		graph_M->add_edge(v1,v2,weight);
	    
	}
    // 输出图中所有顶点
    void list_vertices()
	{
	    if(type == LIST)
		graph_L->list_vertices();
	    else
		graph_M->list_vertices();
	}
    // 输出图中所有边
    void list_edges()
	{
	    if(type == LIST)
		graph_L->list_edges();
	    else
		graph_M->list_edges();
	}
    // 打印整个图
    void print_graph()
	{
	    if(type == LIST)
		graph_L->print_graph();
	    else
		graph_M->print_graph();
	}
    // 图的顶点个数
    size_t num_vertices()
	{
	    if(type == LIST)
		return graph_L->num_vertices();
	    else
		return graph_M->num_vertices();
	}
    // 图的边数
    size_t num_edges()
	{
	    if(type == LIST)
		return graph_L->num_edges();
	    else
		return graph_M->num_edges();
	}
};








#else
#endif
